#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<string.h>
int main(int argc ,char *argv[])
{

  //从参数获取服务端要绑定的地址信息——IP地址与端口
  if(argc < 3 )
  {
    printf("usage:./udp_srv 192.168.1.2 9000\n");
    return -1;

  }
  char *srv_ip = argv[1];
  int srv_port = atoi(argv[2]);

  //1.创建套接字
  //int socket(int domain, int type, int protocol)
  int sockfd = socket(AF_INET ,SOCK_DGRAM, IPPROTO_UDP);
  if(sockfd < 0 )
  {
    perror("socket error");
    return -1;
  }
  //2. 绑定地址信息
  //int bind(int sockd, struct sockaddr *addr, socklen_t len);
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(srv_port);

  addr.sin_addr.s_addr = inet_addr(srv_ip);
  socklen_t len = sizeof(addr);
  int ret = bind(sockfd,(struct sockaddr*)&addr,len);

  if(ret <0)
  {

    close(sockfd);
    perror("bind error");
    return -1;
  }
  while(1) {
  //3.接收数据(接收数据的同时，还要接收对端地址信息)
  //ssize_t recvfrom(int sockfd, void* data,int len,int flag,struct sockaddr* addr,socklen_t *alen)
  char buf[4096]= {0};
  struct sockaddr_in client_addr;
  len = sizeof(client_addr);
  ret = recvfrom(sockfd,buf,4095,0,(struct sockaddr*)&client_addr,&len);
  if(ret  < 0)
  {
    close(sockfd);
    perror("recvfrom error");
    return -1;
  }
//inet_ntoa(client_addr.sin_addr) :将网络字节序IP地址转换为字符串IP地址
//ntohs(client_addr.sin_port),buf)：将端口信息转换为主机字节序。
  printf("%s:%d-%s\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),buf);
  //4.发送数据
  //ssize_t sendto(int sockfd,void *data,int len,int flag, structsockaddr* addr,socklen_t alen)
  printf("serve input: ") ;
  fflush(stdout);
  memset(buf,0x00,4096);//情况buf缓冲区内容
  scanf("%s",buf);
  ret = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client_addr,len);
  if(ret  < 0)
  {
    close(sockfd);
    perror("sendto error");
    return -1;
  }

  }
  //5.关闭套接字
  close(sockfd);

  return 0;
}
